package com.qf.air.service.impl;

import com.qf.air.service.ElasticsearchService;
import com.qf.air.util.Date2StringUtil;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.bulk.BulkItemResponse;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * ES实现
 * @author ZJW
 */
@Service
public class ElasticsearchServiceImpl implements ElasticsearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Override
    public void bulk(DocWriteRequest... requests) throws IOException {
        //1. 创建Request
        BulkRequest request = new BulkRequest();

        //2. 设置requests对象
        request.add(requests);

        //3. 执行request
        BulkResponse resp = restHighLevelClient.bulk(request, RequestOptions.DEFAULT);

        //4. 输出结果
        for (BulkItemResponse item : resp.getItems()) {
            System.out.println(item.getResponse().getResult().toString());
        }
    }

    @Override
    public long findAirIndexCount(Map parameters) throws IOException {
        //1. 创建SearchRequest
        SearchRequest request = new SearchRequest();

        //2. 设置查询索引
        request.indices("air");

        //3. 设置查询条件
        SearchSourceBuilder sourceBuilder = getSearchSourceBuilder(parameters);

        request.source(sourceBuilder);

        //4. 发送request获取resp
        SearchResponse resp = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        //5. 解析获取count
        long count = resp.getHits().getTotalHits().value;
        return count;
    }

    private SearchSourceBuilder getSearchSourceBuilder(Map parameters) {
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //3.1 构建boolQuery
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
        //3.2 检测区域id
        Integer districtId = (Integer) parameters.get("districtId");
        if(districtId != null && districtId != 0){
            boolQuery.must(QueryBuilders.termQuery("districtId",districtId));
        }
        //3.3 监测站名称
        String monitoringStation = (String) parameters.get("monitoringStation");
        if(!StringUtils.isEmpty(monitoringStation)){
            boolQuery.must(QueryBuilders.matchQuery("monitoringStation",monitoringStation));
        }
        //3.4 开始时间
        Date startTime = (Date) parameters.get("startTime");
        if(startTime != null){
            String startTimeString = Date2StringUtil.yyMMdd(startTime);
            boolQuery.must(QueryBuilders.rangeQuery("monitorTime").gte(startTimeString));
        }
        //3.5 结束时间
        Date endTime = (Date) parameters.get("endTime");
        if(endTime != null){
            String endTimeString = Date2StringUtil.yyMMdd(endTime);
            boolQuery.must(QueryBuilders.rangeQuery("monitorTime").lte(endTimeString));
        }

        //3.5 将boolQuery设置到sourceBuilder
        sourceBuilder.query(boolQuery);
        return sourceBuilder;
    }



    @Override
    public List<Map> findAirIndexData(Map parameters) throws IOException {
        //1. 构建SearchRequest
        SearchRequest request =  new SearchRequest();
        //2. 设置索引
        request.indices("air");
        //3. 设置查询条件
        SearchSourceBuilder sourceBuilder = getSearchSourceBuilder(parameters);
        //4. 设置分页信息
        Integer page = (Integer) parameters.get("page");
        Integer rows = (Integer) parameters.get("rows");
        sourceBuilder.from((page - 1) * rows);
        sourceBuilder.size(rows);

        //5. 设置高亮信息
        String monitoringStation = (String) parameters.get("monitoringStation");
        if(!StringUtils.isEmpty(monitoringStation)) {
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.field("monitoringStation");
            highlightBuilder.preTags("<span style='color:red;'>");
            highlightBuilder.postTags("</span>");
            highlightBuilder.fragmentSize(100);
            sourceBuilder.highlighter(highlightBuilder);
        }

        request.source(sourceBuilder);

        //6. 执行request，获取resp
        SearchResponse resp = restHighLevelClient.search(request, RequestOptions.DEFAULT);

        //7. 解析数据，封装
        List<Map> data = new ArrayList<>();
        for (SearchHit hit : resp.getHits().getHits()) {
            Map<String, Object> source = hit.getSourceAsMap();
            // 获取高亮字段
            HighlightField highlightField = hit.getHighlightFields().get("monitoringStation");
            if(highlightField != null){
                String monitoringStationHighLighter = highlightField.getFragments()[0].toString();
                source.put("monitoringStation",monitoringStationHighLighter);
            }
            data.add(source);
        }

        //8. 返回
        return data;
    }
}
